package com.jinke.api.modules.ums.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jinke.api.common.api.CommonResult;
import com.jinke.api.common.exception.Asserts;
import com.jinke.api.modules.app.enums.CostComputeEnums;
import com.jinke.api.modules.ums.dto.CostComputeAddOrUpdateDto;
import com.jinke.api.modules.ums.dto.CostComputeSectionDetailDto;
import com.jinke.api.modules.ums.model.CostComputeImmobilization;
import com.jinke.api.modules.ums.model.CostComputeSection;
import com.jinke.api.modules.ums.model.CostComputeStats;
import com.jinke.api.modules.ums.service.*;
import com.jinke.api.modules.ums.vo.CostComputeSectionVO;
import com.jinke.api.modules.ums.vo.CostComputeVO;
import com.jinke.api.security.util.AdminUserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 价格计算
 *
 * @author huang
 * @data 2024-05-15
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CostComputeServiceImpl implements ICostComputeService {
    private final ICostComputeStatsService iCostComputeStatsService;
    private final ICostComputeZipCodeService iCostComputeZipCodeService;
    private final ICostComputeSectionService iCostComputeSectionService;
    private final ICostComputeImmobilizationService iCostComputeImmobilizationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addOrUpdate(List<CostComputeAddOrUpdateDto> dtoList) {
        //删除原来的
        removeBy();
        //新增
        saveBy(dtoList);
        return CommonResult.success();
    }

    @Override
    public CommonResult<List<CostComputeVO>> getInfo() {
        List<CostComputeVO> vos = new ArrayList<>();
        List<CostComputeStats> stats = iCostComputeStatsService.lambdaQuery().list();
        if (CollectionUtil.isNotEmpty(stats)) {
            for (CostComputeStats stat : stats) {
                CostComputeVO vo = new CostComputeVO();
                vo.setType(stat.getType().getValue());
                vo.setName(stat.getName());
                //区间
                if (CostComputeEnums.SECTION.getValue() == stat.getType().getValue()) {
                    List<CostComputeSection> sections = iCostComputeSectionService.lambdaQuery()
                            .eq(CostComputeSection::getStatsId, stat.getId())
                            .list();
                    List<CostComputeSectionVO> vs = sections.stream().map(s -> {
                        CostComputeSectionVO costComputeSectionVO = new CostComputeSectionVO();
                        BeanUtil.copyProperties(s, costComputeSectionVO);
                        costComputeSectionVO.setSectionCost(s.getCost());
                        return costComputeSectionVO;
                    }).collect(Collectors.toList());
                    vo.setSectionVOList(vs);
                } else {
                    CostComputeImmobilization immobilization = iCostComputeImmobilizationService.lambdaQuery()
                            .eq(CostComputeImmobilization::getStatsId, stat.getId())
                            .one();
                    vo.setImmobilizationCost(immobilization.getCost());
                }
                vos.add(vo);
            }
        }
        return CommonResult.success(vos);
    }

    private void saveBy(List<CostComputeAddOrUpdateDto> dtoList) {
        for (CostComputeAddOrUpdateDto dto : dtoList) {
            CostComputeStats stats = new CostComputeStats();
            BeanUtil.copyProperties(dto, stats);
            stats.setCreateBy(AdminUserUtil.getUserInfo().getUsername());
            iCostComputeStatsService.save(stats);
            //区间
            if (dto.getType() == CostComputeEnums.SECTION.getValue()) {
                if (CollectionUtil.isEmpty(dto.getSectionVOList())) {
                    Asserts.fail("区间范围属性没有数据");
                }
                //重新排序
                List<CostComputeSection> collect = dto.getSectionVOList().stream()
                        .sorted(Comparator.comparing(CostComputeSectionDetailDto::getBegin))
                        .map(s -> {
                            CostComputeSection costComputeSection = new CostComputeSection();
                            BeanUtil.copyProperties(s, costComputeSection);
                            costComputeSection.setStatsId(stats.getId());
                            costComputeSection.setCost(s.getSectionCost());
                            return costComputeSection;
                        })
                        .collect(Collectors.toList());
                iCostComputeSectionService.saveBatch(collect);
            } else {
                //固定
                if (ObjectUtil.isEmpty(dto.getImmobilizationCost())) {
                    Asserts.fail("固定价格属性没有数据");
                }
                CostComputeImmobilization immobilization = new CostComputeImmobilization();
                immobilization.setCost(dto.getImmobilizationCost());
                immobilization.setStatsId(stats.getId());
                iCostComputeImmobilizationService.save(immobilization);
            }
        }
    }

    private void removeBy() {
        List<CostComputeStats> list = iCostComputeStatsService.lambdaQuery().list();
        if (CollectionUtil.isNotEmpty(list)) {
            for (CostComputeStats stats : list) {
                if (stats.getType().getValue() == CostComputeEnums.SECTION.getValue()) {
                    List<CostComputeSection> sections = iCostComputeSectionService.lambdaQuery().eq(CostComputeSection::getStatsId, stats.getId()).list();
                    if (CollectionUtil.isNotEmpty(sections)) {
                        iCostComputeSectionService.removeBatchByIds(sections);
                    }
                } else {
                    iCostComputeImmobilizationService.remove(new LambdaQueryWrapper<CostComputeImmobilization>().eq(CostComputeImmobilization::getStatsId, stats.getId()));
                }
            }
            iCostComputeStatsService.removeBatchByIds(list);
        }
    }
}
